//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Diagnostics;
using OpenLS.Spreadsheet.Collections;
using OpenLS.Spreadsheet.Expressions;
using OpenLS.Spreadsheet.Extensibility;


namespace OpenLS.Spreadsheet
{
    partial class Cell: IDependencyNode
    {
        IRange ICellEnumerator.ToRange()
        {
            return this.ToRange();
        }

        internal void AddDependent(IDependencyNode n)
        {
            promote();
            HashListNoDuplicate<IDependencyNode> dependencies = EnsureExtraData.Dependencies;
            if (dependencies.Contains(n))
                return;
            dependencies.Add(n);
        }
        
        private void removeDependent(IDependencyNode n)
        {

            if (!EnsureExtraData.HasDependents)
                return;
            EnsureExtraData.Dependencies.Remove(n);
            ForgetExtraData();
        }
        internal IEnumerable<IDependencyNode>   GetDependents()
        {
            if (HasExtraData && ExtraData.HasDependents)
            {
                foreach (IDependencyNode c in ExtraData.Dependencies)
                    yield return c;
            }
            
        }

        #region IDependencyNode Members

        IEnumerable<IDependencyNode> IDependencyNode.Dependents()
        {
            return GetDependents();
        }

        #endregion

        #region IDependencyNode Members


        bool IDependencyNode.ProcessChange()
        {
            object o = Value;
                    ChainRecalc();
                    object o2 = Value;
            return (!Equals(o, o2));

        }
        internal void ChainRecalc()
        {
            if (Expression == null)
                return;
            object oldValue = Value;
            object o = Expression.GetNormalizedValue(new CellEvaluationContext(this));
            if (o is Hyperlink)
            {
                this.Hyperlink = (Hyperlink)o;
                this.Value = Hyperlink.Display;
            }
            else
            {
                setRawValue(o);
            }
            CellFormatter.ApplyDateFormat(this, o);
            onValueChanged(oldValue);
            //\\notifyValueChanged();
            notifyRecordPropertyChanged(CellProperty.HorizontalAlignment);
        }

        #endregion

        #region IDependencyNode Members


        void IDependencyNode.ChainRecalc()
        {
            ChainRecalc();
        }

        #endregion

        #region IDependencyNode Members


        void IDependencyNode.AddDependent(IDependencyNode node)
        {
            AddDependent(node);
        }

        #endregion

        #region IDependencyNode Members


        void IDependencyNode.RemoveDependent(IDependencyNode node)
        {
            removeDependent(node);
        }

        #endregion

        internal void AddDependents()
        {
            var set = new Collections.HashSet<IDependencyNode>(_expression.GetPrecedents(new CellEvaluationContext(this)));
            foreach (IDependencyNode node in set)
            {
                node.AddDependent(this);    
                if (node is RangeNodeBase)
                    EnsureExtraData.RangeDependencies.Add   ((RangeNodeBase) node);
            }
        }
    }
}
